using System;
using System.Collections.Generic;
using System.Threading;

namespace Beetle;

public class LRUDetect : IDisposable
{
	public interface IConnecton
	{
		LinkedListNode<Node> Node { get; set; }

		void TimeOut();
	}

	public class Node
	{
		public int LastActiveTime;

		public IConnecton Connection;

		public bool Detect(int cutime, int timeout)
		{
			return Math.Abs(cutime - LastActiveTime) > timeout;
		}
	}

	private int m_a;

	private Timer b;

	private LinkedList<Node> c = new LinkedList<Node>();

	public LRUDetect(int timeout)
	{
		this.m_a = timeout;
		b = new Timer(a, null, this.m_a, this.m_a);
	}

	public void Update(IConnecton connection)
	{
		lock (this)
		{
			LinkedListNode<Node> node = connection.Node;
			if (node != null)
			{
				node.Value.LastActiveTime = Environment.TickCount;
				c.Remove(node);
				c.AddFirst(node);
			}
			else
			{
				node = c.AddFirst(new Node());
				node.Value.LastActiveTime = Environment.TickCount;
				node.Value.Connection = connection;
				connection.Node = node;
			}
		}
	}

	public void Delete(IConnecton connection)
	{
		lock (this)
		{
			LinkedListNode<Node> node = connection.Node;
			if (node != null)
			{
				node.Value.Connection = null;
				c.Remove(node);
			}
		}
	}

	private void a(object A_0)
	{
		lock (this)
		{
			int tickCount = Environment.TickCount;
			LinkedListNode<Node> last = c.Last;
			while (last != null && last.Value.Detect(tickCount, this.m_a))
			{
				last.Value.Connection.TimeOut();
				last.Value.Connection = null;
				c.RemoveLast();
				last = c.Last;
			}
		}
	}

	public void Dispose()
	{
		if (b != null)
		{
			b.Dispose();
			c.Clear();
		}
	}
}
